using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.IO;
using System.IO.IsolatedStorage;
using Sudoku.GamePlay;
using Sudoku.Utilities;
using Microsoft.Xna.Framework;

namespace Services
{
	public class ScoreData
	{
		public int Time;
		public string Name;

		public ScoreData()
		{
			Time = 0;
			Name = "";
		}
	}

	public class HighScore
	{
		public ScoreData Beginner;
		public ScoreData Normal;
		public ScoreData Expert;
		public ScoreData Extreme;

		public HighScore()
		{
			Beginner = new ScoreData();
			Normal = new ScoreData();
			Expert = new ScoreData();
			Extreme = new ScoreData();
		}

		public void SetDifficultyRecord(Difficulty d, int record)
		{
			switch (d)
			{
				case Difficulty.Beginner:
					Beginner.Time = record;
					break;
				case Difficulty.Normal:
					Normal.Time = record;
					break;
				case Difficulty.Experienced:
					Expert.Time = record;
					break;
				case Difficulty.Extreme:
					Extreme.Time = record;
					break;
			}
		}

		public void SetDifficultyRecordName(Difficulty d, string name)
		{
			switch (d)
			{
				case Difficulty.Beginner:
					Beginner.Name = name;
					break;
				case Difficulty.Normal:
					Normal.Name = name;
					break;
				case Difficulty.Experienced:
					Expert.Name = name;
					break;
				case Difficulty.Extreme:
					Extreme.Name = name;
					break;
			}
		}

		public string GetDifficultyRecordName(Difficulty d)
		{
			string s = "";
			switch (d)
			{
				case Difficulty.Beginner:
					s = Beginner.Name;
					break;
				case Difficulty.Normal:
					s = Normal.Name;
					break;
				case Difficulty.Experienced:
					s = Expert.Name;
					break;
				case Difficulty.Extreme:
					s = Extreme.Name;
					break;
			}

			return s;
		}

		public int GetDifficultyRecord(Difficulty d)
		{
			int i = 0;
			switch(d)
			{
				case Difficulty.Beginner:
					i = Beginner.Time;
					break;
				case Difficulty.Normal:
					i = Normal.Time;
					break;
				case Difficulty.Experienced:
					i = Expert.Time;
					break;
				case Difficulty.Extreme:
					i = Extreme.Time;
					break;
			}

			return i;
		}
	}

	public interface IScoreService
	{
		HighScore RetrieveScore();
		void SaveScore(HighScore score);		
	}

	public class ScoreService : IScoreService 
	{
		private Game Game;
		string OldFileName = "Records.xml";
		string FileName = "NewRecords.xml";
		FileIOService FileService;

		public ScoreService(Game game)
		{
			Game = game;
			FileService = (FileIOService)Game.Services.GetService(typeof(FileIOService));

			HighScore score = new HighScore();

			if (FileService.IsFileAvaible(OldFileName))
			{
				score = RetrieveOldScore();
				SaveScore(score);
				FileService.ClearFile(OldFileName);
			}

			if (!FileService.IsFileAvaible(FileName))
			{
				SaveScore(score);
			}
		}

		public void SaveScore(HighScore score)
		{
			FileService.SaveFile(FileName, score, typeof(HighScore));
		}

		public HighScore RetrieveOldScore()
		{
			HighScore score = new HighScore();

			XmlReaderSettings xrs = new XmlReaderSettings();

#if WINDOWS || XBOX
			StreamReader file = new StreamReader(fileName); 

			//Create an XML Writer.
			XmlReader reader = XmlReader.Create(file, xrs);
#else
			IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication();
			IsolatedStorageFileStream isoStream = store.OpenFile(OldFileName, FileMode.Open, FileAccess.Read);
			XmlReader reader = XmlReader.Create(isoStream, xrs);
#endif

			int count = 0;
			while (reader.Read())
			{
				if (reader.NodeType == XmlNodeType.Element && reader.Name == "Level")
				{
					switch (count)
					{
						case 0:
							score.Beginner.Time = int.Parse(reader.GetAttribute(0));
							score.Beginner.Name = reader.GetAttribute(1);
							break;
						case 1:
							score.Normal.Time = int.Parse(reader.GetAttribute(0));
							score.Normal.Name = reader.GetAttribute(1);
							break;
						case 2:
							score.Expert.Time = int.Parse(reader.GetAttribute(0));
							score.Expert.Name = reader.GetAttribute(1);
							break;
						case 3:
							score.Extreme.Time = int.Parse(reader.GetAttribute(0));
							score.Extreme.Name = reader.GetAttribute(1);
							break;
					}
					count++;
				}
			}

			reader.Close();

#if !(WINDOWS || XBOX)
			isoStream.Close();				// Close the IsolatedStorageStream.
			store.Dispose();
#endif

			return score;
		}

		public HighScore RetrieveScore()
		{
			HighScore score = FileService.LoadFile(FileName, typeof(HighScore)) as HighScore;
			return score;
		}

	}
}
